查看原文
其他

到底一台服务器能够支持多少TCP并发连接?

程序猿DD 2020-10-16

The following article is from 朱小厮的博客 Author 朱小厮

点击上方蓝色“程序猿DD”,选择“设为星标”

回复“资源”获取独家整理的学习资料!

作者 | 朱小厮

来源 | 公众号「朱小厮的博客」

曾几何时我们还在寻求网络编程中 C10K 问题的解决方案,但是现在从硬件和操作系统支持来看单台服务器支持上万并发连接已经没有多少挑战性了。有关 C10K(即单机1万个并发连接问题)的信息可以参考《上一个10年,著名的C10K并发连接问题[1]》和《The C10K problem[2]》这两篇文章。

我们先假设单台服务器最多只能支持万级并发连接,其实对绝大多数应用来说已经远远足够了,但是对于一些拥有很大用户基数的互联网公司,往往面临的并发连接数是百万、千万、甚至上亿。虽然现在的集群,分布式技术可以为我们将并发负载分担在多台服务器上,那我们只需要扩展出数十台电脑就可以解决问题,但是我们更希望能更大的挖掘单台服务器的资源,先努力垂直扩展,再进行水平扩展,这样可以有效的节省服务器相关的开支(硬件资源、机房、运维人力、电力其实也是一笔不小的开支)。

那么到底一台服务器能够支持多少TCP并发连接呢?

首先需要考虑文件句柄的限制。在linux下编写网络服务器程序的朋友肯定都知道每一个tcp连接都要占一个文件描述符,一旦这个文件描述符使用完了,新的连接到来返回给我们的错误是“Socket/File:Can't open so many files”。这时你需要明白操作系统对可以打开的最大文件数的限制。我们可以通过 ulimit -n命令、/etc/security/limits.conf 文件 以及 /etc/sysctl.conf 文件等来修改文件句柄数。更多细节可以参阅 「朱小厮的博客」里的这篇文章《文件句柄?文件描述符?傻傻分不清楚》。

其次要考虑的是端口范围的限制。操作系统上端口号1024以下是系统保留的,从1024-65535是用户使用的。由于每个TCP连接都要占一个端口号,所以我们最多可以有60000多个并发连接。我想有这种错误思路朋友不在少数吧?面试官也比较喜欢在这里引导挖坑,类似的问题还有:一个UDP连接可以复用已经被TCP连接占用的端口嘛?(可以在下方留言区留下你的答案。)

如何标识一个TCP连接? 系统使用一个4四元组来唯一标识一个TCP连接:本地端口号 local port、本地IP地址 local ip、远端端口号 remote port、远端IP地址 remote ip。server通常固定在某个本地端口上监听,等待client的连接请求。不考虑地址重用(unix的SO_REUSEADDR选项)的情况下,即使server端有多个ip,本地监听端口也是独占的,因此server端tcp连接4元组中只有remote ip(也就是client ip)和remote port(客户端port)是可变的,因此最大tcp连接为客户端ip数×客户端port数,对IPV4,不考虑ip地址分类等因素,最大tcp连接数约为2的32次方(ip数)×2的16次方(port数),也就是server端单机最大tcp连接数约为2的48次方。

上面给出的结论都是理论上的单机TCP并发连接数,实际上单机并发连接数肯定要受硬件资源(内存)、网络资源(带宽)的限制,至少对我们的需求现在可以做到数十万级的并发了。

参考资料

[1]

上一个10年,著名的C10K并发连接问题: http://www.52im.net/thread-566-1-1.html

[2]

The C10K problem: http://www.kegel.com/c10k.html



往期推荐



轻轻一扫,立刻扣款,付款码背后的原理你不想知道吗?

 Windows 20 概念视频,这才是用户所需要的操作系统?

同事埋了个坑:Insert into select语句把生产服务器炸了

相同 SQL 下 Mybatis 查询结果和数据库竟然不一样!

Star 10.9K!这份Google面试攻略,牛逼了!


扫一扫,关注我

一起学习,一起进步

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存